package edu.cmu.cs.stage3.alice.core.behavior;

import edu.cmu.cs.stage3.alice.core.Question;
import edu.cmu.cs.stage3.alice.core.RenderTarget;
import edu.cmu.cs.stage3.alice.core.Transformable;
import edu.cmu.cs.stage3.alice.core.Variable;
import edu.cmu.cs.stage3.alice.core.World;
import edu.cmu.cs.stage3.alice.core.property.ElementArrayProperty;
import edu.cmu.cs.stage3.alice.core.property.IntegerProperty;
import edu.cmu.cs.stage3.alice.core.property.TransformableProperty;
import edu.cmu.cs.stage3.alice.core.question.PickQuestion;

public class MouseButtonClickBehavior extends TriggerBehavior implements java.awt.event.MouseListener {

 private static Class[] s_supportedCoercionClasses = { MouseButtonIsPressedBehavior.class };

 //Rem @Override
 public Class[] getSupportedCoercionClasses() {
  return s_supportedCoercionClasses;
 }
 public final IntegerProperty requiredModifierMask = new IntegerProperty( this, "requiredModifierMask", new Integer( 0 ) );
 public final IntegerProperty excludedModifierMask = new IntegerProperty( this, "excludedModifierMask", new Integer( 0 ) );
 public final ElementArrayProperty renderTargets = new ElementArrayProperty( this, "renderTargets", null, edu.cmu.cs.stage3.alice.core.RenderTarget[].class );

 //should this be a ModelProperty?
 public final TransformableProperty onWhat = new TransformableProperty( this, "onWhat", null );

 private edu.cmu.cs.stage3.alice.core.RenderTarget[] m_renderTargets = null;
 private java.awt.event.MouseEvent m_pressedEvent = null;
 public long m_clickTimeThreshold = 300;
 public int m_clickDistanceThresholdSquared = 100;

 //Rem @Override
 public void manufactureAnyNecessaryDetails() {
  if( details.size()==2 ) {
   Question what = new PickQuestion();
   what.name.set( "what" );
   what.setParent( this );
   details.add( what );
  }
  for( int i=0; i<details.size(); i++ ) {
   Object o = details.get( i );
   if( o instanceof PickQuestion ) {
    ((PickQuestion)o).name.set( "what" );
   }
  }
 }
 //Rem @Override
 public void manufactureDetails() {
  super.manufactureDetails();

  Variable x = new Variable();
  x.name.set( "x" );
  x.setParent( this );
  x.valueClass.set( Number.class );
  details.add( x );

  Variable y = new Variable();
  y.name.set( "y" );
  y.setParent( this );
  y.valueClass.set( Number.class );
  details.add( y );

  manufactureAnyNecessaryDetails();
 }
 private boolean checkModifierMask( java.awt.event.InputEvent e ) {
  int modifiers = e.getModifiers();
  Integer requiredModifierMaskValue = (Integer)requiredModifierMask.getValue();
  Integer excludedModifierMaskValue = (Integer)excludedModifierMask.getValue();
  int required = 0;
  if( requiredModifierMaskValue!=null ) {
   required = requiredModifierMaskValue.intValue();
  }
  int excluded = 0;
  if( excludedModifierMaskValue!=null ) {
   excluded = excludedModifierMaskValue.intValue();
  }
  return ( ( modifiers&required ) == required ) && ( ( modifiers&excluded ) == 0 );
 }

 public void mouseClicked( java.awt.event.MouseEvent mouseEvent ) {
 }
 public void mouseEntered( java.awt.event.MouseEvent mouseEvent ) {
 }
 public void mouseExited( java.awt.event.MouseEvent mouseEvent ) {
 }
 public void mousePressed( java.awt.event.MouseEvent mouseEvent ) {
  m_pressedEvent = mouseEvent;
 }

 public void mouseReleased( java.awt.event.MouseEvent mouseEvent ) {
  int dx = mouseEvent.getX() - m_pressedEvent.getX();
  int dy = mouseEvent.getY() - m_pressedEvent.getY();
  long dt = mouseEvent.getWhen() - m_pressedEvent.getWhen();
  if( dt < m_clickTimeThreshold ) {
   if( dx*dx + dy*dy < m_clickDistanceThresholdSquared ) {
    if( isEnabled.booleanValue() ) {
     if( checkModifierMask( mouseEvent ) ) {
      Transformable onWhatValue = onWhat.getTransformableValue();
      if( onWhatValue!=null ) {
      } else {
      }
     }
    }
   }
  }
 }
 //Rem @Override
 protected void started( World world, double time ) {
  super.started( world, time );
  m_renderTargets = (RenderTarget[])renderTargets.get();
  if( m_renderTargets==null ) {
   m_renderTargets = (RenderTarget[])world.getDescendants( RenderTarget.class );
  }
  //LOB for (RenderTarget target : m_renderTargets)
  int t_tam = m_renderTargets!=null ? m_renderTargets.length : 0;
  for (int i_i=0; i_i<t_tam; i_i++) {
   m_renderTargets[i_i].addMouseListener( this ); //L target.addMouseListener( this );
  }
 }
 //Rem @Override
 protected void stopped( World world, double time ) {
  super.stopped( world, time );
  //LOB for (RenderTarget target : m_renderTargets)
  int t_tam = m_renderTargets!=null ? m_renderTargets.length : 0;
  for (int i_i=0; i_i<t_tam; i_i++) {
   m_renderTargets[i_i].removeMouseListener( this ); //L target.removeMouseListener( this );
  }
  m_renderTargets = null;
 }

}
